package cn.exrick.xboot.modules.activiti.serviceimpl;

import cn.exrick.xboot.common.utils.SecurityUtil;
import cn.exrick.xboot.common.vo.SearchVo;
import cn.exrick.xboot.modules.activiti.dao.ActBusinessDao;
import cn.exrick.xboot.modules.activiti.entity.ActBusiness;
import cn.exrick.xboot.modules.activiti.service.ActBusinessService;
import cn.exrick.xboot.modules.base.entity.Department;
import cn.exrick.xboot.modules.base.entity.Role;
import cn.exrick.xboot.modules.base.entity.User;
import cn.exrick.xboot.modules.base.service.DepartmentService;
import cn.exrick.xboot.modules.base.service.UserRoleService;
import cn.exrick.xboot.modules.base.service.UserService;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.lang.Nullable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.persistence.criteria.*;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * 业务申请接口实现
 * @author Exrick
 */
@Slf4j
@Service
@Transactional
public class ActBusinessServiceImpl implements ActBusinessService {

    @Autowired
    private ActBusinessDao actBusinessDao;

    @Autowired
    private UserService userService;

    @Autowired
    private SecurityUtil securityUtil;

    @Autowired
    private DepartmentService departmentService;

    @Autowired
    private UserRoleService userRoleService;

    @Override
    public ActBusinessDao getRepository() {
        return actBusinessDao;
    }

    @Override
    public Page<ActBusiness> findByCondition(ActBusiness actBusiness, SearchVo searchVo, Pageable pageable) {

        return actBusinessDao.findAll(new Specification<ActBusiness>() {
            @Nullable
            @Override
            public Predicate toPredicate(Root<ActBusiness> root, CriteriaQuery<?> cq, CriteriaBuilder cb) {


                Path<String> titleField = root.get("title");
                Path<Integer> statusField = root.get("status");
                Path<Integer> resultField = root.get("result");
                Path<Date> createTimeField = root.get("createTime");
                Path<Date> applyTimeField = root.get("applyTime");
                Path<String> userIdField = root.get("userId");
                Path<String> procDefIdField = root.get("procDefId");
                Path<String> workId = root.get("workId");


                List<Predicate> list = new ArrayList<Predicate>();

                // 模糊搜素
                if(StrUtil.isNotBlank(actBusiness.getTitle())){
                    list.add(cb.like(titleField,'%'+actBusiness.getTitle()+'%'));
                }
                // 工单搜素
                if(StrUtil.isNotBlank(actBusiness.getWorkId())){
                    list.add(cb.like(workId,'%'+actBusiness.getWorkId()+'%'));
                }

                // 状态
                if(actBusiness.getStatus()!=null){
                    list.add(cb.equal(statusField, actBusiness.getStatus()));
                }
                // 结果
                if(actBusiness.getResult()!=null){
                    list.add(cb.equal(resultField, actBusiness.getResult()));
                }

                // 创建时间
//                if(StrUtil.isNotBlank(searchVo.getStartDate())&&StrUtil.isNotBlank(searchVo.getEndDate())){
//                    Date start = DateUtil.parse(searchVo.getStartDate());
//                    Date end = DateUtil.parse(searchVo.getEndDate());
//                    list.add(cb.between(createTimeField, start, DateUtil.endOfDay(end)));
//                }
                // 派单时间
                if(StrUtil.isNotBlank(searchVo.getStartDate())&&StrUtil.isNotBlank(searchVo.getEndDate())){
                    Date start = DateUtil.parse(searchVo.getStartDate());
                    Date end = DateUtil.parse(searchVo.getEndDate());
                    list.add(cb.between(applyTimeField, start, DateUtil.endOfDay(end)));
                }



                {
                    // 用户换成部门所有人
                    //获取所辖地区部门
                    List<String> allRolesName = new ArrayList<>();
                    List<String> allRolesFullName = new ArrayList<>();
                    List<String> allDepartIds = new ArrayList<>();
                    boolean isHeader = false;
                    for (Role r : securityUtil.getCurrUser().getRoles()) {
                        String[] spliceItems = r.getName().split("_");
                        if (spliceItems.length == 3) {
                            allRolesName.add(spliceItems[1]);
                            allRolesFullName.add("ROLE_" + spliceItems[1] + "_网格员");
                        }else{
                            if (r.getName().indexOf("镇长") >= 0 || r.getName().indexOf("书记") >= 0){
                                isHeader = true;
                            }
                        }
                    }

                    if (!isHeader){
                        List<Department> allDepart = departmentService.findByTitleInOrderBySortOrder(allRolesName);
                        for (Department d : allDepart) {
                            allDepartIds.add(d.getId());
                        }
                        allDepartIds.add(securityUtil.getCurrUser().getDepartmentId());
                        List<User> allUser = userService.findByDepartmentInId(allDepartIds);
                        List<String> allUserId = new ArrayList<>();
                        for (User u : allUser) {
                            allUserId.add(u.getId());
                        }
                        List<String> creater = userService.findUserIdByRoleNameIn(allRolesFullName);
                        allUserId.addAll(creater);
                        list.add(userIdField.in(allUserId));
                    }
                    //获取角色所辖派单员数据
                }
                list.add(cb.notEqual(procDefIdField, ""));

                Predicate[] arr = new Predicate[list.size()];
                cq.where(list.toArray(arr));
                return null;
            }
        }, pageable);
    }

    @Override
    public List<ActBusiness> findByProcDefId(String procDefId) {
        return actBusinessDao.findByProcDefId(procDefId);
    }

    @Override
    public ActBusiness findByProcInstId(String procInstId) {
        return actBusinessDao.findByProcInstId(procInstId);
    }
}